#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define BUFFER_SIZE 5

// 定义环形队列结构体
typedef struct {
    int data[BUFFER_SIZE];
    int head;
    int tail;
    int count;
} CircularBuffer;

// 初始化环形队列
void init_buffer(CircularBuffer *buffer) {
    buffer->head = 0;
    buffer->tail = 0;
    buffer->count = 0;
}

// 判断环形队列是否已满
int is_full(CircularBuffer *buffer) {
    return buffer->count == BUFFER_SIZE;
}

// 判断环形队列是否为空
int is_empty(CircularBuffer *buffer) {
    return buffer->count == 0;
}

// 生产者函数
void* producer(void *arg) {
    CircularBuffer *buffer = (CircularBuffer*)arg;
    sem_t *empty = sem_open("empty", O_CREAT, 0666, BUFFER_SIZE);
    sem_t *full = sem_open("full", O_CREAT, 0666, 0);
    sem_t *mutex = sem_open("mutex", O_CREAT, 0666, 1);

    while (1) {
        sem_wait(empty);
        sem_wait(mutex);

        // 生产数据并放入队列
        int data = rand() % 100; // 假设生产的数据是0到99之间的随机数
        buffer->data[buffer->head] = data;
        printf("生产者生产了数据: %d\n", data);

        buffer->head = (buffer->head + 1) % BUFFER_SIZE;
        buffer->count++;

        sem_post(mutex);
        sem_post(full);
    }

    return NULL;
}

// 消费者函数
void* consumer(void *arg) {
    CircularBuffer *buffer = (CircularBuffer*)arg;
    sem_t *empty = sem_open("empty", O_CREAT, 0666, 0);
    sem_t *full = sem_open("full", O_CREAT, 0666, BUFFER_SIZE);
    sem_t *mutex = sem_open("mutex", O_CREAT, 0666, 1);

    while (1) {
        sem_wait(full);
        sem_wait(mutex);

        // 从队列取出数据并消费
        int data = buffer->data[buffer->tail];
        printf("消费者消费了数据: %d\n", data);

        buffer->tail = (buffer->tail + 1) % BUFFER_SIZE;
        buffer->count--;

        sem_post(mutex);
        sem_post(empty);
    }

    return NULL;
}

int main() {
    CircularBuffer buffer;
    init_buffer(&buffer);

    pthread_t producer_thread, consumer_thread;
    sem_t *empty, *full, *mutex;

    // 创建信号量
    empty = sem_open("empty", O_CREAT, 0666, BUFFER_SIZE);
    full = sem_open("full", O_CREAT, 0666, 0);
    mutex = sem_open("mutex", O_CREAT, 0666, 1);

    // 创建生产者线程
    pthread_create(&producer_thread, NULL, producer, &buffer);
    // 创建消费者线程
    pthread_create(&consumer_thread, NULL, consumer, &buffer);

    // 等待线程结束
    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);

    // 关闭信号量
    sem_close(empty);
    sem_close(full);
    sem_close(mutex);

    return 0;
}